﻿using System;

namespace Microsoft.Popfly.GameCreator.GameEngine
{
    public static class PhysicsUtils
    {
        public static double GetNewVelocity(
            double elapsedTimeInSeconds,
            double drag,
            double velocity,
            double acceleration)
        {
            if (drag == 1.0)
            {
                return acceleration;
            }
            else if (drag == 0.0)
            {
                return (velocity + (acceleration * elapsedTimeInSeconds));
            }
            else
            {
                // potential simplifying of this for perf reasons
                // the non-integral form of :
                //return velocity + (acceleration * elapsedTimeInSeconds) - 
                //    (drag * velocity) * elapsedTimeInSeconds;// incorporate drag

                // Original integral form:
                double inverseDrag = 1.0 - drag;
                return (Math.Pow(inverseDrag, elapsedTimeInSeconds) * velocity +
                        acceleration * (1 - Math.Pow(inverseDrag, elapsedTimeInSeconds)) /
                        (1 - inverseDrag));
            }
        }

        // most of these parameters are unnecessary
        // if we're doing the static calculation, but if we 
        // do the integral, they are necessary
        public static double GetNewPosition(
            double elapsedTimeInSeconds,
            double drag,
            double position,
            double acceleration,
            double updatedVelocity,
            double startingVelocity)
        {
            if (drag == 0 || drag == 1)
            {
                return position + updatedVelocity * elapsedTimeInSeconds;
            }
            else
            {
              

                // original integral form:
                double inverseDrag = 1.0 - drag;
                return position + (
                        -((acceleration * elapsedTimeInSeconds) / (-1 + inverseDrag)) +
                          (acceleration * Math.Pow(inverseDrag, elapsedTimeInSeconds)) / ((-1 + inverseDrag) * Math.Log(inverseDrag)) +
                          (Math.Pow(inverseDrag, elapsedTimeInSeconds) * startingVelocity) / Math.Log(inverseDrag) +
                         -(acceleration / (inverseDrag - 1) + startingVelocity) / Math.Log(inverseDrag)
                       );
            }
        }
    }
}
